/*
 * All rights Reserved, Designed By DataDriver
 * Copyright:    DataDriver.Inc
 * Company:      Zhuo Wo Infomation Technology (ShangHai) CO.LTD
 */
package com.sun.pc;

public class D {


    /**
     * 在使用wait方法时使用if语句的判断会出现虚假唤醒的操作
     * 官网建议wait线程阻塞时在while的循环体中包起来
     * @param args
     */
    public static void main(String[] args) {
       Food food = new Food();

       new Thread(()->{
           for (int i = 0; i < 10; i++) {
               try {
                   food.incream();
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
       },"A").start();

        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    food.decre();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"B").start();

        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    food.decre();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"C").start();

        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    food.incream();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"D").start();

    }

}


/**
 * Synchronized锁，使用wait进行线程等待，notifyAll()进行线程的唤醒操作
 * 但是需要注意的是不能使用if语句进行判断，wait应该在while的循环体中
 */

class Food {
    private int num = 0;

    public synchronized  void incream() throws InterruptedException {
        while (num != 0) {
           //等待
            this.wait();
        }
        System.out.println(Thread.currentThread().getName() + "=>" + num);
        num ++;
        this.notifyAll();
    }

    public synchronized void decre() throws InterruptedException {
        while (num == 0) {
          //等待新增
            this.wait();
        }
        System.out.println(Thread.currentThread().getName() + "=>" + num);
        num --;
        //通知其他线程我加1完毕了
        this.notifyAll();
    }
}
